package com.xmall.sys.service.impl.other;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmall.define.base.Result;
import com.xmall.define.constants.CommonConstants;
import com.xmall.define.constants.CommonProperties;
import com.xmall.define.dto.log.RetryLogDto;
import com.xmall.define.dto.log.RetryLogTimerTaskDto;
import com.xmall.define.request.sys.RetryLogListPageQueryRequest;
import com.xmall.sys.service.other.IRetryLogTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class RetryLogTaskServiceImpl implements IRetryLogTaskService {

    @Resource
    private DiscoveryClient client;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private CommonProperties commonProperties;

    /**
     * 任务列表
     */
    @Override
    public List<RetryLogTimerTaskDto> taskList() {
        List<RetryLogTimerTaskDto> timerTaskDtoList = new ArrayList<>();

        client.getServices().forEach(service -> {
            client.getInstances(service).forEach(instance -> {
                try {
                    String serviceIp = (instance.isSecure() ? "https" : "http") + "://" + instance.getHost() + ":" + instance.getPort();
                    String requestUrl = serviceIp + CommonConstants.TimerTask.RETRY_LOG_TASK_LIST_REQUEST_URL;

                    Result<String> result = restTemplate.getForObject(requestUrl, Result.class);
                    if(result.callSuccess()) {
                        JSON.parseArray(result.getData(), RetryLogTimerTaskDto.class).forEach(taskDto -> {
                            taskDto.setServiceName(service);
                            taskDto.setServiceIp(serviceIp);
                            timerTaskDtoList.add(taskDto);
                        });
                    }
                }catch (Exception e) {
                    if(!(e instanceof HttpClientErrorException.NotFound)) {
                        log.error("remote service for taskList error: {}, service: {}, ip: {}", e.getMessage(), service, instance.getHost() + ":" + instance.getPort());
                    }
                }
            });
        });

        return timerTaskDtoList;
    }

    /**
     * 重试日志分页列表
     */
    @Override
    public Page<RetryLogDto> logListPage(RetryLogListPageQueryRequest request) {
        try {
            ParameterizedTypeReference<Page<RetryLogDto>> type = new  ParameterizedTypeReference<Page<RetryLogDto>>() {};

            String url = UriComponentsBuilder.fromHttpUrl(request.getServiceIp() + CommonConstants.TimerTask.RETRY_LOG_LIST_PAGE_REQUEST_URL)
                .queryParam("page", request.getPage())
                .queryParam("pageSize", request.getPageSize())
                .queryParam("key", request.getTaskKey())
                .build().toUriString();

            Result<String> result = restTemplate.getForObject(url, Result.class);
            if(result.callSuccess()) {
                Page<RetryLogDto> logPage = JSON.parseObject(result.getData(), type.getType());
                logPage.getRecords().forEach(retryLog -> retryLog.setIsMaxRetry(commonProperties.getLogRetryIntervalSecondsList().size() <= retryLog.getRetryCount()));
                return logPage;
            }
        }catch (Exception e) {
            log.error("remote service for retryLogList error: {}, ip: {}, taskKey: {}", e.getMessage(), request.getServiceIp(), request.getTaskKey());
        }
        return new Page<>();
    }
}
